package dcq;

import org.gdal.gdal.gdal;
import org.gdal.ogr.*;

import java.util.Objects;


public class GDALConvertTool {


    public static void main(String[] ags) {

//        shp2geojson();
//        clearpglyr();
        shp2pg();


    }
    public static  void shp2geojson(){

        // 注册所有的驱动
        ogr.RegisterAll();
        // 为了支持中文路径，请添加下面这句代码
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","YES");
        // 为了使属性表字段支持中文，请添加下面这句
        gdal.SetConfigOption("SHAPE_ENCODING","");

        String strVectorFile = "E:\\workproject_0\\gdal\\my-gdal-java-demo\\my-gdal-java-demo\\gisdata\\jjhxzj84.shp";
        //打开数据
        DataSource shpDataSource = ogr.Open(strVectorFile,0);
        String authority = shpDataSource.GetLayer(0).GetSpatialRef().GetAttrValue("AUTHORITY", 1);
        System.out.println("坐标系: " + authority);
        if (shpDataSource == null)
        {
            System.out.println("打开文件失败！" );
            return;
        }
        System.out.println("打开文件成功！" );
        Driver geojsonDriver = ogr.GetDriverByName("GeoJSON");
        if (geojsonDriver == null)
        {
            System.out.println("打开驱动失败！" );
            return;
        }
        System.out.println("打开驱动成功！" );
        String outStrVectorFile = "E:\\workproject_0\\gdal\\my-gdal-java-demo\\my-gdal-java-demo\\gisdata\\shp2geojson.json";
        geojsonDriver.CopyDataSource(shpDataSource, outStrVectorFile);
        System.out.println("转换成功！" );

    }

    public static void pg2geojson() {
        ogr.RegisterAll();
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");//同时设置shp文件的读写编码
        //获取pg驱动
        String pgDriverName = "PostgreSQL";
        Driver pgDriver = ogr.GetDriverByName(pgDriverName);
        if (pgDriver == null) {
            System.out.println("不支持" + pgDriverName + "驱动");
            return;
        }
        //GDAL连接PostGIS
        String path = "PG:dbname=postgis_32_sample host=localhost port=5432 user=postgres password=123456";
        DataSource pgDataSource = pgDriver.Open(path, 0);
        if (pgDataSource == null) {
            System.out.println("GDAL连接PostGIS数据库失败!");
            return;
        }
        String strSQL = "SELECT gid, smuserid, name, geoguid, angle, geom FROM public.jjhxzj84;";
        //获取图层
        Layer pgLayer = pgDataSource.ExecuteSQL(strSQL);     //创建矢量文件
        String strVectorFile = "E:\\workproject_0\\gdal\\my-gdal-java-demo\\my-gdal-java-demo\\gisdata\\pg2geojson.json";
        //驱动
        String geojsonDriverName = "GEOJSON";
        Driver geojsonDriver = ogr.GetDriverByName(geojsonDriverName);
        if (geojsonDriver == null) {
            System.out.println(geojsonDriverName + " 驱动不可用！\n");
            return;
        }
        //数据源
        DataSource geojsonDataSource = geojsonDriver.CreateDataSource(strVectorFile, null);
        if (geojsonDataSource == null) {
            System.out.println("创建矢量文件【" + strVectorFile + "】失败！\n");
            return;
        }

        // 拷贝图层数据
        geojsonDataSource.CopyLayer(pgLayer, "jjhxzj84");

        geojsonDataSource.delete();
        geojsonDriver.delete();
        gdal.GDALDestroyDriverManager();
        System.out.println("geojson文件创建成功");

    }

    //pg库导出shp
    public static void pg2shpv1() {
        ogr.RegisterAll();
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");//同时设置shp文件的读写编码
        //获取pg驱动
        String pgDriverName = "PostgreSQL";
        org.gdal.ogr.Driver pgDriver = ogr.GetDriverByName(pgDriverName);
        if (pgDriver == null) {
            System.out.println("不支持" + pgDriverName + "驱动");
            return;
        }
        //GDAL连接PostGIS
        String path = "PG:dbname=postgis_32_sample host=localhost port=5432 user=postgres password=123456";
        DataSource pgDataSource = pgDriver.Open(path, 0);
        if (pgDataSource == null) {
            System.out.println("GDAL连接PostGIS数据库失败!");
            return;
        }
        String strSQL = "SELECT gid, smuserid, name, geoguid, angle, geom FROM public.jjhxzj84;";
        //获取图层
        Layer pgLayer = pgDataSource.ExecuteSQL(strSQL);
        //Layer pgLayer = pgDataSource.GetLayerByName("jjhxzj84");
        if (pgLayer == null) {
            System.out.println("获取【" + "jjhxzj84" + "】图层失败！");
            return;
        }
        System.out.println(pgLayer.GetFIDColumn());

        //创建矢量文件
        String strVectorFile = "E:\\workproject_0\\gdal\\my-gdal-java-demo\\my-gdal-java-demo\\gisdata\\pg2shp-gbk.shp";
        //驱动
        String shpDriverName = "ESRI Shapefile";
        org.gdal.ogr.Driver shpDriver = ogr.GetDriverByName(shpDriverName);
        if (shpDriver == null) {
            System.out.println(shpDriverName + " 驱动不可用！\n");
            return;
        }
        //数据源
        DataSource shpDataSource = shpDriver.CreateDataSource(strVectorFile, null);
        if (shpDataSource == null) {
            System.out.println("创建矢量文件【" + strVectorFile + "】失败！\n");
            return;
        }
        //图层
        Layer shpLayer = shpDataSource.CreateLayer("", pgLayer.GetSpatialRef(), pgLayer.GetGeomType());
        if (shpLayer == null) {
            System.out.println("图层创建失败！\n");
            return;
        }
        //字段
        FeatureDefn pgDefn = pgLayer.GetLayerDefn();
        int iFieldCount = pgDefn.GetFieldCount();
        for (int i = 0; i < iFieldCount; i++) {
            FieldDefn oField = pgDefn.GetFieldDefn(i);
            shpLayer.CreateField(oField, 1);
        }
        //数据记录
        Feature oFeature = null;
        while ((oFeature = pgLayer.GetNextFeature()) != null) {
            System.out.println(oFeature.GetFID());
            shpLayer.CreateFeature(oFeature);
        }
        //写入文件
        shpLayer.SyncToDisk();
        shpDataSource.SyncToDisk();
        //删除数据源
        pgDataSource.delete();
        shpDataSource.delete();
        gdal.GDALDestroyDriverManager();
        System.out.println("shp文件创建成功！");
    }

    //pg库导出shp
    public static void pg2shpv2() {
        ogr.RegisterAll();
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");//同时设置shp文件的读写编码
        //获取pg驱动
        String pgDriverName = "PostgreSQL";
        org.gdal.ogr.Driver pgDriver = ogr.GetDriverByName(pgDriverName);
        if (pgDriver == null) {
            System.out.println("不支持" + pgDriverName + "驱动");
            return;
        }

        //GDAL连接PostGIS
        StringBuffer pgConnetcBuff = new StringBuffer();
        pgConnetcBuff.append("PG:dbname=").append("postgis_32_sample")//数据库名称
                .append(" host=").append("localhost")//主机地址
                .append(" port=").append("5432")//端口
                .append(" user=").append("postgres")//用户名称
                .append(" password=").append("123456");//密码
        String path = pgConnetcBuff.toString();
        DataSource pgDataSource = pgDriver.Open(path, 0);
        //获取图层
        Layer pgLayer = pgDataSource.GetLayerByName("jjhxzj84");
        if (Objects.isNull(pgLayer)) {
            System.out.println("获取图层失败");
            return;
        }
        //创建矢量文件
        String strVectorFile = "E:\\workproject_0\\gdal\\my-gdal-java-demo\\my-gdal-java-demo\\gisdata\\pg2shp-gbk.shp";

        Driver driver = ogr.GetDriverByName("ESRI Shapefile");
        DataSource dataSource = driver.CreateDataSource(strVectorFile);
        // 拷贝图层数据
        dataSource.CopyLayer(pgLayer, "jjhxzj84");

        dataSource.delete();
        driver.delete();
        gdal.GDALDestroyDriverManager();
        System.out.println("shp文件创建成功");

    }

    public static void  clearpglyr(){

        ogr.RegisterAll();
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");//同时设置shp文件的读写编码
        //获取pg驱动
        String pgDriverName = "PostgreSQL";
        org.gdal.ogr.Driver pgDriver = ogr.GetDriverByName(pgDriverName);
        if (pgDriver == null) {
            System.out.println("不支持" + pgDriverName + "驱动");
            return;
        }
        //GDAL连接PostGIS
        String path = "PG:dbname=postgis_32_sample host=localhost port=5432 user=postgres password=123456";
        DataSource pgDataSource = pgDriver.Open(path, 0);
        if (pgDataSource == null) {
            System.out.println("GDAL连接PostGIS数据库失败!");
            return;
        }
        String strSQL = "DELETE FROM jjhxzj84v2 WHERE 1=1;";
        //
        Layer pgLayer = pgDataSource.ExecuteSQL(strSQL);
        //删除数据源
        pgDataSource.delete();
        gdal.GDALDestroyDriverManager();
        System.out.println("pg图层要素清除成功1！");

    }

    /**
     * 注意1：pg库导入shp（FID会冲突，需要自己解决）
     * 注意2：用 pgLayer.CreateFeature(oFeature)，shp导入pg数据库，gdal会默认给shp添加一个fid字段。
     * 该方式空间数据入库的前提条件：
     * shp和pg空间表字段一致，且pg表有fid字段.
     * 注意3： pgLayer.CreateFeature(oFeature)入库，oFeature自身的srid被丢弃，
     * 录入pg空间表的该几何列的表定义的坐标系不变，新加入空间表的几何字段的坐标系都为空间表原定义的srid.
     */
    public static void shp2pg() {
        ogr.RegisterAll();
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        gdal.SetConfigOption("SHAPE_ENCODING", "");

        String shpDriverName = "ESRI Shapefile";
        org.gdal.ogr.Driver shpDriver = ogr.GetDriverByName(shpDriverName);
        if (shpDriver == null) {
            System.out.println(shpDriverName + " 驱动不可用！\n");
            return;
        }

        String strVectorFile = "E:\\workproject_0\\gdal\\my-gdal-java-demo\\my-gdal-java-demo\\gisdata\\pg2shp.shp";
        DataSource shpDataSource = ogr.Open(strVectorFile, 0);
        if (shpDataSource == null) {
            System.out.println("打开文件【" + strVectorFile + "】失败！");
            return;
        }
        Layer shpLayer = shpDataSource.GetLayerByIndex(0);
        if (shpLayer == null) {
            System.out.println("获取shp图层失败！\n");
            return;
        }
        System.out.println(shpLayer.GetFIDColumn());

        //获取pg驱动
        String pgDriverName = "PostgreSQL";
        org.gdal.ogr.Driver pgDriver = ogr.GetDriverByName(pgDriverName);
        if (pgDriver == null) {
            System.out.println("不支持" + pgDriverName + "驱动");
            return;
        }
        //GDAL连接PostGIS
        String path = "PG:dbname=postgis_32_sample host=localhost port=5432 user=postgres password=123456";
        DataSource pgDataSource = pgDriver.Open(path, 1);
        if (pgDataSource == null) {
            System.out.println("GDAL连接PostGIS数据库失败!");
            return;
        }
        //获取图层
        Layer pgLayer = pgDataSource.GetLayerByName("jjhxzj84v2");
        if (pgLayer == null) {
            System.out.println("获取【" + "tablename" + "】图层失败！");
            return;
        }

        Feature oFeature = null;
        Long lyrFeaCount = pgLayer.GetFeatureCount();
        // 创建Vector并添加要忽略的字段名称 ，无效
//        Vector<String> ignoredFields = new Vector<>();
//        ignoredFields.add(shpLayer.GetFIDColumn());
//        shpLayer.SetIgnoredFields(ignoredFields);
        while ((oFeature = shpLayer.GetNextFeature()) != null) {
            //获取要素属性
            int feildCount = oFeature.GetFieldCount();
            for (int p = 0; p < feildCount; p++) {
                FieldDefn fieldDefn = oFeature.GetFieldDefnRef(p);
                System.out.println(fieldDefn.GetName() + ","
                        + fieldDefn.GetFieldType() + ","
                        + fieldDefn.GetTypeName() + ","
                        + GDALHelper.getProperty(oFeature, p)
                );

            }


            System.out.println(oFeature.GetFID() + 1);
//                oFeature.SetFID(-1);
            pgLayer.CreateFeature(oFeature);

        }
        //写入文件
        pgLayer.SyncToDisk();
        pgDataSource.SyncToDisk();

//        pgLayer.CommitTransaction();//，无效
//        pgDataSource.CommitTransaction();
        //删除数据源
        pgDataSource.delete();
        shpDataSource.delete();
        gdal.GDALDestroyDriverManager();
        System.out.println("shp文件导入成功！");

    }

}
